#include "csapp.h"
#include "sbuf.h"
#define NTHREADS 4
#define SBUFSIZE 16
typedef struct sockaddr SA;
sbuf_t sbuf;
void echo(int connfd){
	size_t n;
	char buf[MAXLINE];
	rio_t rio;
	Rio_readinitb(&rio,connfd);
	while(1){
		n=Rio_readlineb(&rio,buf,MAXLINE);
		if(n==0) break;
		fputs(buf,stdout);		
		Rio_writen(connfd,buf,n);
	}
	return;
}
void *thread(){
	Pthread_detach(pthread_self());
	int connfd;
	while(1){
		connfd=sbuf_remove(&sbuf);
		echo(connfd);
		Close(connfd);
	}
	return NULL;
}
int main(int argc,char **argv){
	int i,listenfd,connfd;
	socklen_t clientlen;
	struct sockaddr_storage clientaddr;// Ensure the store is enough
	char client_hostname[MAXLINE],client_port[MAXLINE];
	pthread_t tid;
	if(argc!=2){//More than one input 
		fprintf(stderr,"usage:%s <port>\n",argv[0]);
		exit(0);
	}
	listenfd = Open_listenfd( atoi(argv[1]) );
	for(i=0;i<NTHREADS;++i) Pthread_create(&tid,NULL,thread,NULL);
	sbuf_init(&sbuf,SBUFSIZE);
	while(1){
		clientlen = sizeof(struct sockaddr_storage);
		connfd= Accept(listenfd,(SA *)&clientaddr,&clientlen);
		sbuf_insert(&sbuf,connfd);
	}
	exit(0);
}
